package ru.kreda.webapp.client;

import ru.kreda.webapp.client.ui.ErrorUIDialog;
import ru.kreda.webapp.shared.AppException;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.UmbrellaException;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.InvocationException;

/**
 * Обработчик ошибок.
 */
public class ErrorHandler implements GWT.UncaughtExceptionHandler {

	@Override
	public void onUncaughtException(Throwable e) {
		handle(e);
	}

	/**
	 * Отображает окно с ошибкой пользователю.
	 * 
	 * @param caught
	 *            ошибка
	 */
	public static void handle(Throwable caught) {
		GWT.log("ErrorHandler", caught);
		String[] details = getDetails(caught);
		ErrorUIDialog uiDialog = new ErrorUIDialog(details[0], details[1]);
		uiDialog.show();
	}

	private static String[] getDetails(Throwable caught) {
		String message;
		String stackTrace;
		if (caught instanceof UmbrellaException) {
			message = "";
			stackTrace = "";
			for (Throwable cause : ((UmbrellaException) caught).getCauses()) {
				String[] details = getDetails(cause);
				message += details[0];
				if (details[1] != null) {
					stackTrace += details[1];
				}
			}
		} else {
			if (caught instanceof IncompatibleRemoteServiceException) {
				// this client is not compatible with the server; cleanup and
				// refresh the browser
				message = "Ошибка взаимодействия с сервером";
				stackTrace = "";
			} else if (caught instanceof InvocationException) {
				// the call didn't complete cleanly
				message = "Произошла ошибка при обращении к серверу";
				stackTrace = "";
			} else if (caught instanceof AppException) {
				// one of the 'throws' from the original method
				message = caught.getMessage();
				stackTrace = ((AppException) caught).getStackTraceString();
			} else {
				message = caught.getMessage();
				stackTrace = "";
			}
		}
		return new String[] { message, stackTrace };
	}

}
